package com.google.code.biglo.compiler;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.Resource;

import com.google.code.biglo.lang.BpmnDefinition;
import com.google.code.biglo.lang.bpmn.model.DefinitionsDocument;
import com.google.code.biglo.lang.bpmn.model.TDefinitions;
import com.google.code.biglo.lang.bpmn.model.TFlowElement;
import com.google.code.biglo.lang.bpmn.model.TFlowNode;
import com.google.code.biglo.lang.bpmn.model.TProcess;
import com.google.code.biglo.lang.bpmn.model.TRootElement;
import com.google.code.biglo.lang.bpmn.model.TSequenceFlow;

public class BpmnCompiler {
    private static Log log = LogFactory.getLog(BpmnCompiler.class);
    
	public static List<BpmnDefinition> compile(List<Resource> resources) throws Exception {
		return new BpmnCompiler().compileInternal(resources);
	}
	
	private List<BpmnDefinition> compileInternal(List<Resource> resources) throws Exception {
		List<BpmnDefinition> defs = new ArrayList<BpmnDefinition>();
		for (Resource resource : resources) {
			TDefinitions defs2 = DefinitionsDocument.Factory.parse(resource.getInputStream()).getDefinitions();
			for (TRootElement root : defs2.getRootElementArray()) {
				if (root instanceof TProcess) {
					BpmnDefinition d = new BpmnDefinition();
					d.process = (TProcess) root;
					compileTransitions(d);
					defs.add(d);
				}
			}
		}
		return defs;
	}
	
	private void compileTransitions(BpmnDefinition bpmn) {
		for (TFlowElement e : bpmn.process.getFlowElementArray()) {
			if (e instanceof TFlowNode) {
				bpmn.nodes.put(e.getId(), (TFlowNode) e);
			} else if (e instanceof TSequenceFlow) {
				TSequenceFlow seq = (TSequenceFlow) e;
				List<TSequenceFlow> l = bpmn.outgoing.get(seq.getSourceRef());
				if (l == null) {
					l = new ArrayList<TSequenceFlow>();
					bpmn.outgoing.put(seq.getSourceRef(), l);
				}
				l.add(seq);
				bpmn.outgoing.put(seq.getSourceRef(), l);
			}
			log.debug(e.toString());
		}
	}
}
